
package cn.sylinx.web.template.velocity;

import java.io.StringWriter;

import org.apache.velocity.Template;
import org.apache.velocity.context.Context;

import cn.sylinx.web.log.GLog;

public class VelocityLayoutTemplateEngineImpl extends VelocityTemplateEngineImpl {

	/**
	 * The context key that will hold the content of the screen.
	 *
	 * This key ($screen_content) must be present in the layout template for the
	 * current screen to be rendered.
	 */
	public static final String KEY_SCREEN_CONTENT = "screen_content";

	/**
	 * The context/parameter key used to specify an alternate layout to be used
	 * for a request instead of the default layout.
	 */
	public static final String KEY_LAYOUT = "layout";

	public static final String DEFAULT_LAYOUT_DIR = "/layout/";

	public static final String DEFAULT_LAYOUT = "default.vm";

	@Override
	protected String mergeTemplate(Template template, Context context) {

		StringWriter sw = new StringWriter();
		template.merge(context, sw);
		// Add the resulting content to the context
		context.put(KEY_SCREEN_CONTENT, sw.toString());

		// Check for an alternate layout
		//
		// we check after merging the screen template so the screen
		// can overrule any layout set in the request parameters
		// by doing #set( $layout = "MyLayout.vm" )
		Object obj = context.get(KEY_LAYOUT);
		String layout = (obj == null) ? null : obj.toString();
		if (layout == null) {
			layout = getTemplateDirectory() + DEFAULT_LAYOUT_DIR + DEFAULT_LAYOUT;
		} else {
			layout = getTemplateDirectory() + DEFAULT_LAYOUT_DIR + layout;
		}

		try {
			// load the layout template
			template = getTemplate(layout);
		} catch (Exception e) {
			GLog.error("Can't load layout \"" + layout + "\"", e);

			if (!layout.equals(DEFAULT_LAYOUT)) {
				template = getTemplate(getTemplateDirectory() + DEFAULT_LAYOUT_DIR + DEFAULT_LAYOUT);
			}
		}

		return super.mergeTemplate(template, context);
	}
}
